package cn.com.hellowood.springsecurity.config;

import cn.com.hellowood.springsecurity.security.CustomAuthenticationProvider;
import cn.com.hellowood.springsecurity.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

/**
 * The type Security config.
 *
 * @author HelloWood
 */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String INTERNAL_SECRET_KEY="fsdfas";

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;


    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // This is permitted for all user
        http.authorizeRequests()
                .antMatchers("/", "/login", "/login-error", "/css/**", "/index")
                .permitAll();

        // Others url is need authenticate to access
        http.authorizeRequests()
                .anyRequest()
                .authenticated();


//        // 只需要以下配置即可启用记住密码
//        http.authorizeRequests()
//                .and()
//                .rememberMe()
//                .userDetailsService(userDetailsService)
////                .rememberMeServices(rememberMeServices())
//                .rememberMeParameter("remember-me")
//                .tokenValiditySeconds(1209600)
//                .key(INTERNAL_SECRET_KEY);



        // 持久化数据库记住密码
        http.authorizeRequests()
                .and()
                .rememberMe()
                .userDetailsService(userDetailsService)
                .tokenRepository(persistentTokenRepository())
//                .rememberMeServices(rememberMeServices())
                .rememberMeParameter("remember-me")
                .tokenValiditySeconds(1209600)
                ;

        // This config require login form action is '/login' and username and password parameter name is
        // 'username' and 'password', and login fail url is 'login-error'
        http.formLogin()
                .loginPage("/login")
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .failureUrl("/login?error")
//                .failureUrl("/login-error")
                ;


        //以下这句就可以控制单个用户只能创建一个session，也就只能在服务器登录一次
        http.sessionManagement().maximumSessions(1).expiredUrl("/login");
    }



    //使用remember-me必须指定UserDetailsService
//    @Override
//    protected UserDetailsService userDetailsService() {
//        return userDetailsService;
//    }



//    /**
//     * 返回 RememberMeServices 实例
//     *
//     * @return the remember me services
//     */
//    @Bean
//    public RememberMeServices rememberMeServices() {
//        JdbcTokenRepositoryImpl rememberMeTokenRepository = new JdbcTokenRepositoryImpl();
//        // 此处需要设置数据源，否则无法从数据库查询验证信息
//        rememberMeTokenRepository.setDataSource(dataSource);
//
//        // 此处的 key 可以为任意非空值(null 或 "")，单必须和起前面
//        // rememberMeServices(RememberMeServices rememberMeServices).key(key)的值相同
//        PersistentTokenBasedRememberMeServices rememberMeServices =
//                new PersistentTokenBasedRememberMeServices(INTERNAL_SECRET_KEY, userDetailsService, rememberMeTokenRepository);
//
//        // 该参数不是必须的，默认值为 "remember-me", 但如果设置必须和页面复选框的 name 一致
//        rememberMeServices.setParameter("remember-me");
//        return rememberMeServices;
//    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
        db.setDataSource(dataSource());
        return db;
    }

    @Bean(name = "dataSource")
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
        driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
        driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/security");
        driverManagerDataSource.setUsername("root");
        driverManagerDataSource.setPassword("pass");
        return driverManagerDataSource;
    }


    /**
     * Configure global.
     *
     * @param auth the auth
     * @throws Exception the exception
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(customAuthenticationProvider);

    }


}
